package com.wyzz.hr.bo.impl;

import com.wyzz.hr.bo.IEmpBenefitBo;
import com.wyzz.hr.bo.IEmpBenefitPlanBo;
import com.wyzz.hr.bo.IEmpSalaryAcctitemsBo;
import com.wyzz.hr.bo.IEmployeeBo;
import com.wyzz.hr.dao.IEmpBenefitDao;
import com.wyzz.hr.pojo.BenefitType;
import com.wyzz.hr.pojo.Empbenefit;
import com.wyzz.hr.pojo.Empbenefitplan;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Empsalaryacctitems;
import com.wyzz.hr.pojo.Empsalaryconfig;
import com.wyzz.hr.pojo.Empsalarypay;
import com.wyzz.hr.spring.SpringBeanFactory;
import com.wyzz.hr.util.DateUtil;
import com.wyzz.hr.util.MyTools;
import com.wyzz.hr.util.Pager;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import org.apache.log4j.Logger;
import org.hibernate.FetchMode;
import org.hibernate.criterion.*;
import org.springframework.util.ObjectUtils;

public class EmpBenefitBoImpl implements IEmpBenefitBo {

	public EmpBenefitBoImpl() {
	}

	public List findEmpBenefit(DetachedCriteria dc, Pager page,
			String searchOrExport) {
		if (page == null || "export".equals(searchOrExport)) {
			return empBenefitDao.findByCriteria(dc);
		} else {
			page.splitPage(dc);
			return empBenefitDao.findByCriteria(dc, page.getPageSize(), page
					.getCurrentPage());
		}
	}

	/**
	 * @deprecated Method insertBenefit is deprecated
	 */

	public String insertBenefit(Empbenefit benefit, String currEmpId) {
		String error = "";
		IEmployeeBo empBo = (IEmployeeBo) SpringBeanFactory.getBean("empBo");
		Employee emp = empBo.loadEmp(benefit.getEmployee().getId(), null);
		Empbenefit oldBenefit = emp.getBenefit();
		if (oldBenefit != null) {
			if (benefit.getEbfStartMonth().compareTo(
					oldBenefit.getEbfStartMonth()) < 0) {
				error = (new StringBuilder())
						.append(emp.getEmpName())
						.append(
								"\u8C03\u6574\u8BB0\u5F55\u7684\u751F\u6548\u5E74\u6708\u4E0D\u80FD\u65E9\u4E8E\u539F\u8BB0\u5F55\u7684\u751F\u6548\u5E74\u6708\uFF01")
						.toString();
				return error;
			}
			oldBenefit.setEbfEndMonth(DateUtil.yearMonthAdd(benefit
					.getEbfStartMonth(), -1, 2));
			empBenefitDao.updateObject(oldBenefit);
		}
		benefit.setEbfId(getUUID());
		empBenefitDao.saveObject(benefit);
		if (benefit.getBeneType() != null
				&& !"".equals(benefit.getBeneType().trim()))
			emp.setEmpBenefitType(new BenefitType(benefit.getBeneType()));
		if (benefit != null)
			emp.setBenefit(benefit);
		emp.setEmpLastChangeBy(new Employee(currEmpId));
		emp.setEmpLastChangeTime(new Date());
		empBenefitDao.updateObject(emp);
		return error;
	}

	public String insertNewBenefit(Empbenefit oldEbf, Empbenefit newEbf,
			Employee emp) {
		empBenefitDao.updateObject(oldEbf);
		empBenefitDao.saveObject(newEbf);
		empBenefitDao.updateObject(emp);
		if (emp.getConfig() != null)
			empBenefitDao.updateObject(emp.getConfig());
		return "SUCC";
	}

	public String addBenefit(Employee emp) {
		Date lastChangeTime = new Date();
		Empbenefit newEbf = emp.getBenefit();
		newEbf.setEbfId(MyTools.getUUID());
		newEbf.setEmployee(new Employee(emp.getId()));
		empBenefitDao.saveObject(newEbf);
		emp.setEmpLastChangeTime(lastChangeTime);
		empBenefitDao.updateObject(emp);
		Empsalaryconfig config = emp.getConfig();
		if (config != null) {
			config.setEscLastChangeTime(lastChangeTime);
			config.setEscLastChangeBy(emp.getEmpLastChangeBy().getId());
			config.encryEmpSalaryConf(config);
			empBenefitDao.updateObject(config);
		}
		return "SUCC";
	}

	public String updateBenefit(Empbenefit oldEbf, Employee emp) {
		Date lastChangeTime = new Date();
		if (oldEbf != null) {
			String ebfEndMonth = DateUtil.yearMonthAdd(emp.getBenefit()
					.getEbfStartMonth(), -1, 2);
			oldEbf.setEbfEndMonth(ebfEndMonth);
			empBenefitDao.updateObject(oldEbf);
		}
		Empbenefit newEbf = emp.getBenefit();
		newEbf.setEmployee(emp);
		newEbf.setEbfId(emp.getBenefit().getEbfId());
		empBenefitDao.updateObject(newEbf);
		emp.setEmpLastChangeTime(lastChangeTime);
		empBenefitDao.updateObject(emp);
		Empsalaryconfig config = emp.getConfig();
		if (config != null) {
			config.setEscLastChangeTime(lastChangeTime);
			config.setEscLastChangeBy(emp.getEmpLastChangeBy().getId());
			config.encryEmpSalaryConf(config);
			empBenefitDao.updateObject(config);
		}
		return "SUCC";
	}

	public String deleteBenefit(Employee employee, String ebfId, String empNo) {
		String hql = (new StringBuilder()).append(
				"delete from Empbenefit where ebfId='").append(ebfId).append(
				"'").toString();
		empBenefitDao.exeHql(hql);
		List oldList = searchByEmpNo(employee.getId());
		employee.setEmpLastChangeBy(new Employee(empNo));
		employee.setEmpLastChangeTime(new Date());
		if (oldList != null && oldList.size() > 0) {
			Empbenefit old = (Empbenefit) oldList.get(0);
			old.setEbfEndMonth(null);
			old.setEmployee(employee);
			empBenefitDao.updateObject(old);
			employee.setBenefit(old);
			empBenefitDao.updateObject(employee);
		} else {
			employee.setBenefit(null);
			empBenefitDao.updateObject(employee);
		}
		return null;
	}

	public boolean deleteBenefitPlan(String yearmonth, Integer status,
			String empIds[]) {
		if (empIds == null || empIds.length == 0)
			return false;
		StringBuffer hqlBuffer = new StringBuffer();
		String arr$[] = empIds;
		int len$ = arr$.length;
		for (int i$ = 0; i$ < len$; i$++) {
			String empId = arr$[i$];
			hqlBuffer.append((new StringBuilder()).append("ebpEmpno.id='")
					.append(empId).append("' or ").toString());
		}

		String hql = (new StringBuilder()).append(
				"delete from Empbenefitplan where ebpYearMonth='").append(
				yearmonth).append("' and ").toString();
		if (status != null)
			hql = (new StringBuilder()).append(hql).append("ebpStatus='")
					.append(status).append("' and ").toString();
		hql = (new StringBuilder()).append(hql).append("(").append(
				hqlBuffer.toString()).toString();
		hql = (new StringBuilder()).append(hql.substring(0, hql.length() - 3))
				.append(")").toString();
		empBenefitDao.exeHql(hql);
		return true;
	}

	public List searchByEmpNo(String employeeId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empbenefit.class);
		detachedCriteria.setFetchMode(Empbenefit.PROP_EBF_EMPLOYEE,
				FetchMode.DEFAULT);
		detachedCriteria.add(Restrictions.eq((new StringBuilder()).append(
				Empbenefit.PROP_EBF_EMPLOYEE).append(".").append(
				Employee.PROP_ID).toString(), employeeId));
		detachedCriteria
				.addOrder(Order.desc(Empbenefit.PROP_EBF_EBFSTARTMONTH));
		List result = empBenefitDao.findByCriteria(detachedCriteria);
		return result;
	}

	public Empbenefit loadPrevBenefit(String employeeId) {
		List beneList = searchByEmpNo(employeeId);
		if (beneList.size() < 2)
			return null;
		else
			return (Empbenefit) beneList.get(1);
	}

	public Empbenefit getEmpbenefitById(String ebfId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empbenefit.class);
		detachedCriteria.setFetchMode(Empbenefit.PROP_EBF_EMPLOYEE,
				FetchMode.DEFAULT);
		detachedCriteria.add(Restrictions.eq(Empbenefit.PROP_EBF_EBFID, ebfId));
		List result = empBenefitDao.findByCriteria(detachedCriteria);
		if (result.size() == 0)
			return null;
		else
			return (Empbenefit) result.get(0);
	}

	public List searchbenefitpayvalueByEmpId(String empId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalarypay.class);
		detachedCriteria.createAlias("espEmpno", "emp", 1);
		detachedCriteria.setFetchMode("espEmpconfig", FetchMode.JOIN);
		detachedCriteria.setFetchMode("espEmpconfig.escJobgrade",
				FetchMode.JOIN);
		detachedCriteria.add(Restrictions.eq("emp.id", empId));
		detachedCriteria.addOrder(Order.desc(Empsalarypay.PROP_ESP_YEARMONTH));
		List payList = empBenefitDao.findByCriteria(detachedCriteria);
		if (payList.isEmpty())
			return new ArrayList();
		IEmpSalaryAcctitemsBo esaiBo = (IEmpSalaryAcctitemsBo) SpringBeanFactory
				.getBean("empsalaryacctitemsBo");
		if (!esaiBo.setAcctItemsPay((Empsalarypay[]) payList
				.toArray(new Empsalarypay[payList.size()])))
			return null;
		IEmpBenefitPlanBo ebpBo = (IEmpBenefitPlanBo) SpringBeanFactory
				.getBean("empbenefitplanBo");
		Map monthsumplanMap = ebpBo.getSumEbpsOfAllMonth(payList);
		List items = null;
		Empbenefitplan sumplan = null;
		Empsalarypay pay = null;
		for (int i = 0; payList != null && i < payList.size(); i++) {
			pay = (Empsalarypay) payList.get(i);
			items = pay.getAcctItems();
			sumplan = (Empbenefitplan) monthsumplanMap
					.get((new StringBuilder()).append(empId).append("").append(
							pay.getEspYearmonth()).toString());
			try {
				payList.set(i, calcBenePayForPage(items, pay, sumplan));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return payList;
	}

	private Empsalarypay calcBenePayForPage(List items, Empsalarypay pay,
			Empbenefitplan sumplan) {
		Empsalarypay payTemp = null;
		try {
			payTemp = (Empsalarypay) pay.clone();
		} catch (CloneNotSupportedException e1) {
			e1.printStackTrace();
		}
		List sumList = new ArrayList();
		for (int i = 0; i <= 20; i++)
			sumList.add(new BigDecimal(0));

		Class planClass = Empbenefitplan.class;
		BigDecimal sumValue = null;
		int i = 0;
		for (int j = items.size(); i < j; i++) {
			Empsalaryacctitems esai = (Empsalaryacctitems) items.get(i);
			try {
				Method ebpMethod = planClass.getMethod((new StringBuilder())
						.append("getEbpColumn").append(esai.getEsaiDataSeq())
						.toString(), new Class[0]);
				if (sumplan != null)
					sumValue = (BigDecimal) ebpMethod.invoke(sumplan,
							new Object[0]);
				if (sumValue != null)
					sumList.set(
							esai.getEsaiEsdd().getEsddDataType().intValue(),
							((BigDecimal) sumList.get(esai.getEsaiEsdd()
									.getEsddDataType().intValue()))
									.add(sumValue));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		payTemp.setYearAndMonth(pay.getEspYearmonth());
		payTemp.setShowColumn15((BigDecimal) sumList.get(15));
		payTemp.setShowColumn16((BigDecimal) sumList.get(16));
		return payTemp;
	}

	public void setEmpBenefitPay(String yearmonth, Empsalarypay payList[]) {
		if (ObjectUtils.isEmpty(payList))
			return;
		List payListCurr = new ArrayList();
		List payListNext = new ArrayList();
		Empsalarypay arr$[] = payList;
		int len$ = arr$.length;
		for (int i$ = 0; i$ < len$; i$++) {
			Empsalarypay pay = arr$[i$];
			Employee emp = pay.getEspEmpno();
			emp.setBenefit(null);
			if (emp.getEmpBenefitType() == null)
				continue;
			pay.setBenefitType(emp.getEmpBenefitType());
			if (emp.getEmpBenefitType().getBenefitTypePayType().equals(
					Integer.valueOf(0)))
				payListCurr.add(pay);
			else
				payListNext.add(pay);
		}

		getEmpBenefit(yearmonth, 0, payListCurr);
		getEmpBenefit(yearmonth, 1, payListNext);
	}

	public void getEmpBenefitEbp(String yearMonth, List empList) {
		if (empList == null || empList.size() == 0)
			return;
		getEmpBenefit(yearMonth, empList);
		for (Iterator i$ = empList.iterator(); i$.hasNext();) {
			Employee emp = (Employee) i$.next();
			emp.getBenefit().setBelongYearMonth(yearMonth);
			if (emp.getEmpBenefitType().getBenefitTypePayType().equals(
					Integer.valueOf(1)))
				yearMonth = DateUtil.yearMonthAdd(yearMonth, -1, 2);
			emp.getBenefit().setEspYearMonth(yearMonth);
			try {
				Empbenefit benefitEmp = (Empbenefit) emp.getBenefit().clone();
				emp.setBenefit(benefitEmp);
				benefitEmp.setEmployee(emp);
			} catch (CloneNotSupportedException e) {
				e.printStackTrace();
			}
		}

	}

	public void getEmpBenefit(String yearMonth, int isNext, List payList) {
		if (payList == null || payList.size() == 0)
			return;
		String beneYearMonth = yearMonth;
		if (isNext == 1)
			beneYearMonth = DateUtil.yearMonthAdd(yearMonth, 1, 2);
		DetachedCriteria dc = DetachedCriteria.forClass(Empbenefit.class);
		Map payMap = new HashMap();
		Set empIds = new HashSet();
		Empsalarypay pay;
		Employee emp;
		for (Iterator i$ = payList.iterator(); i$.hasNext(); payMap.put(emp
				.getId(), pay)) {
			pay = (Empsalarypay) i$.next();
			emp = pay.getEspEmpno();
			empIds.add(emp.getId());
		}

		if (empIds.size() < 500)
			dc.add(Restrictions.in((new StringBuilder()).append(
					Empbenefit.PROP_EBF_EMPLOYEE).append(".").append(
					Employee.PROP_ID).toString(), empIds));
		dc.add(Restrictions.and(Restrictions.le(
				Empbenefit.PROP_EBF_EBFSTARTMONTH, beneYearMonth), Restrictions
				.disjunction().add(
						Restrictions.ge(Empbenefit.PROP_EBF_EBFENDMONTH,
								beneYearMonth)).add(
						Restrictions.isNull(Empbenefit.PROP_EBF_EBFENDMONTH))));
		List benefitList = empBenefitDao.findByCriteria(dc);
		if (benefitList == null || benefitList.size() == 0)
			return;
		Iterator i$ = benefitList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Empbenefit benefit = (Empbenefit) i$.next();
			benefit.setBelongYearMonth(beneYearMonth);
			Empsalarypay pay1 = (Empsalarypay) payMap.get(benefit.getEmployee()
					.getId());
			if (pay1 != null)
				pay1.setBenefit(benefit);
		} while (true);
	}

	public void getEmpBenefit(String yearMonth, List empList) {
		if (empList == null || empList.size() == 0)
			return;
		DetachedCriteria dc = DetachedCriteria.forClass(Empbenefit.class);
		Map empMap = new HashMap();
		Set empIds = new HashSet();
		Employee emp;
		for (Iterator i$ = empList.iterator(); i$.hasNext(); empMap.put(emp
				.getId(), emp)) {
			emp = (Employee) i$.next();
			empIds.add(emp.getId());
		}

		if (empIds.size() < 500)
			dc.add(Restrictions.in((new StringBuilder()).append(
					Empbenefit.PROP_EBF_EMPLOYEE).append(".").append(
					Employee.PROP_ID).toString(), empIds));
		dc.add(Restrictions.and(Restrictions.le(
				Empbenefit.PROP_EBF_EBFSTARTMONTH, yearMonth), Restrictions
				.disjunction().add(
						Restrictions.ge(Empbenefit.PROP_EBF_EBFENDMONTH,
								yearMonth)).add(
						Restrictions.isNull(Empbenefit.PROP_EBF_EBFENDMONTH))));
		List benefitList = empBenefitDao.findByCriteria(dc);
		if (benefitList == null || benefitList.size() == 0)
			return;
		Iterator i$ = benefitList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Empbenefit benefit = (Empbenefit) i$.next();
			Employee emp1 = (Employee) empMap
					.get(benefit.getEmployee().getId());
			if (emp1 != null)
				emp1.setBenefit(benefit);
		} while (true);
	}

	public List getEmpAdditionalBenefitPlanList(String belongYearMonth,
			Set empIds) {
		if (empIds.isEmpty()) {
			return new ArrayList(0);
		} else {
			DetachedCriteria detachedCriteria = DetachedCriteria
					.forClass(Empbenefitplan.class);
			detachedCriteria.add(Restrictions.in("ebpEmpno.id", empIds));
			detachedCriteria.add(Restrictions.eq("ebpBelongYearmonth",
					belongYearMonth));
			return empBenefitDao.findByCriteria(detachedCriteria);
		}
	}

	private Map getEmpBenefitPlanMap(String empId) {
		StringBuffer hqlBuffer = new StringBuffer(
				"select ebpYearMonth,sum(ebpHousingAmountb),sum(ebpInsuranceAmountb),sum(ebpPensionAmountb) from Empbenefitplan ");
		hqlBuffer.append(" where ebpEmpno.id ='");
		hqlBuffer.append(empId);
		hqlBuffer.append("' group by ebpYearMonth");
		List result = empBenefitDao.exeHqlList(hqlBuffer.toString());
		if (result.isEmpty())
			return new HashMap(0);
		Map resultMap = new HashMap();
		Object obj[];
		Empbenefitplan plan;
		for (Iterator i$ = result.iterator(); i$.hasNext(); resultMap.put(
				(String) obj[0], plan)) {
			obj = (Object[]) i$.next();
			plan = new Empbenefitplan();
			plan.setEbpBelongYearmonth((String) obj[0]);
			plan.setEbpHousingAmountb((BigDecimal) obj[1]);
			plan.setEbpInsuranceAmountb((BigDecimal) obj[2]);
			plan.setEbpPensionAmountb((BigDecimal) obj[3]);
		}

		return resultMap;
	}

	public List getBenefitPlanByEsav(String esavId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empbenefitplan.class);
		detachedCriteria.add(Restrictions.eq("ebpEsavId.id", esavId));
		return empBenefitDao.findByCriteria(detachedCriteria);
	}

	public boolean shuffleBenefitPlan(List<Empbenefitplan> planList,
			Map fromMap, List toItems) {
		for (Empbenefitplan plan : planList) {
			try {
				Empbenefitplan clonePlan = (Empbenefitplan) plan.clone();
				String empId = plan.getEbpEmpno().getId();
				for (int j = 0; j < toItems.size(); ++j) {
					String dataDefId = ((Empsalaryacctitems) toItems.get(j))
							.getEsaiEsdd().getEsddId();
					Integer fromPos = (Integer) fromMap.get(dataDefId);
					BigDecimal getValue;
					if (fromPos != null) {
						if (fromPos.intValue() == j)
							continue;
						Method getMethod = Empbenefitplan.class.getMethod(
								"getEbpColumn" + (fromPos.intValue() + 1),
								new Class[0]);
						getValue = (BigDecimal) getMethod.invoke(clonePlan,
								new Object[0]);
					} else {
						getValue = MyTools.encryDecimal(empId,
								new BigDecimal(0));
					}
					Method setMethod = Empbenefitplan.class.getMethod(
							"setEbpColumn" + (j + 1),
							new Class[] { BigDecimal.class });
					setMethod.invoke(plan, new Object[] { getValue });
				}
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
		}
		return true;
	}

	public boolean saveOrupdate(List planList) {
		empBenefitDao.saveOrupdate(planList);
		return true;
	}

	public IEmpBenefitDao getEmpBenefitDao() {
		return empBenefitDao;
	}

	public void setEmpBenefitDao(IEmpBenefitDao empBenefitDao) {
		this.empBenefitDao = empBenefitDao;
	}

	private String getUUID() {
		UUID uuid = UUID.randomUUID();
		return uuid.toString();
	}

	private static final Logger logger = Logger
			.getLogger(EmpBenefitBoImpl.class);
	private IEmpBenefitDao empBenefitDao;

}
